<?php
interface IVisitor {}

interface IASTNode {
	public function accept(IVisitor $visitor);
}

interface IASTDirective {}

interface IASTLocatable {
	public function getLineNumber();
}

class ASTParseDirective implements IASTNode {

	public $resource;
	public $line;
	public $escapes;
	
	public function accept(IVisitor $visitor) {
		$visitor->visitParseDirective($this);	
	}
}

class ASTIncludeDirective implements IASTNode {

	public $resource;
	public $line;
	public $escapes;
	
	public function accept(IVisitor $visitor) {
		$visitor->visitIncludeDirective($this);	
	}
}

class ASTStopDirective implements IASTNode {
	
	public $escapes;
	
	public function accept(IVisitor $visitor) {
		$visitor->visitStopDirective($this);
	}
}

class ASTArray implements IASTNode {
	
	public $elements;

	function __construct() {
		$this->elements = array();
	}
	
	public function accept(IVisitor $visitor) {
		$visitor->visitArray($this);	
	}
}

class ASTArrayRange implements IASTNode {

	public $left;
	public $right;
	
	public function accept(IVisitor $visitor) {
		$visitor->visitArrayRange($this);	
	}
}

class ASTInterpolation implements IASTNode {
	
	public $expression;	
	
	public function accept(IVisitor $visitor) {
		$visitor->visitInterpolation($this);
	}
}

class ASTMacro implements IASTNode, IASTDirective {

	public $name;
	public $parameters;
	public $block;
	
	public function accept(IVisitor $visitor) {
		$visitor->visitMacro($this);
	}
}

class ASTMacroCall implements IASTNode, IASTDirective {

	public $smurk;
	public $name;
	public $parameters;
	public $escapes;
	
	public function accept(IVisitor $visitor) {
		$visitor->visitMacroCall($this);
	}
}

class ASTReference implements IASTNode {
	
	public $elements;
	public $smurk;
	
	/**
	 * @var int $escapes Number of escape '/' characters proceeding this reference
	 */
	public $escapes;
	
	function __construct() {
		$this->elements = array();
	}
	
	public function addElement(IASTReferenceElement $element) {
		$this->elements[] = $element;	
	}
	
	public function accept(IVisitor $visitor) {
		$visitor->visitReference($this);
	}
}

abstract class IASTReferenceElement implements IASTNode {
	
	public $name;
	
	public function getName() {
		return $this->name;
	}
}

class ASTReferenceName extends IASTReferenceElement {
	
	public function __construct($name) {
		$this->name = $name;
	}
	
	public function accept(IVisitor $visitor) {
		$visitor->visit($this);
	}
}

class ASTReferenceArray extends IASTReferenceElement {
	
	public $key;
	
	public function __construct($name) {
		$this->name = $name;
	}

	public function accept(IVisitor $visitor) {
		$visitor->visit($this);
	}
}

class ASTReferenceMethod extends IASTReferenceElement {
	
	public $parameters;
	
	public function __construct($name) {
		$this->name = $name;
	}
	
	public function accept(IVisitor $visitor) {
		$visitor->visit($this);
	}
}

class ASTModifier implements IASTNode {
	
	public $name;
	public $parameters;
	
	public function accept(IVisitor $visitor) {
		
	}
}

class ASTEndDirective implements IASTNode, IASTDirective {
	
	var $escapes;
	
	public function accept(IVisitor $visitor) {
		$visitor->visit($this);
	}
}

class ASTIfDirective implements IASTNode, IASTDirective {
	
	public $condition;
	public $trueBlock;
	public $falseBlock;
	public $escapes;
	public $end;
	
	function __construct($condition, $trueBlock, $falseBlock) {
		$this->condition = $condition;
		$this->trueBlock = $trueBlock;
		$this->falseBlock = $falseBlock;
	}
	
	public function setFalseBlock($block) {
		$this->falseBlock = $block;
	}
	
	public function accept(IVisitor $visitor) {
		$visitor->visitIfDirective($this);
	}
}

class ASTElseIfDirective extends ASTIfDirective {
	
	public $escapes;
	
	public function accept(IVisitor $visitor) {
		$visitor->visitElseIfDirective($this);
	}
}

class ASTElseDirective implements IASTNode, IASTDirective {
	
	public $block;
	public $escapes;
	
	public function __construct($block) {
		$this->block = $block;
	}
	
	public function accept(IVisitor $visitor) {
		$visitor->visitElseDirective($this);
	}
}

class ASTSetDirective implements IASTNode, IASTDirective {
	
	/**
	 * @var ASTReference
	 */
	public $reference;
	
	/**
	 * @var ASTExpr
	 */
	public $expression;
	
	public $escapes;
	
	function __construct($reference, $expression) {
		$this->reference = $reference;
		$this->expression = $expression;
	}
	
	public function accept(IVisitor $visitor) {
		$visitor->visitSetDirective($this);
	}
}

class ASTForeachDirective implements IASTNode, IASTDirective, IASTLocatable {

	/**
	 * @var ASTReference
	 */
	public $key;
	
	/**
	 * @var ASTReference
	 */
	public $array;
	
	/**
	 * @var ASTBlock
	 */
	public $loopBlock;
	
	/**
	 * The else block
	 *
	 * @var ASTBlock
	 */
	public $else;
	
	/**
	 * Get the linenumber
	 */
	public $line;
	
	public $escapes;
	
	/**
	 * Enter description here...
	 *
	 * @param ASTNode $array The that contains the array to loop through
	 * @param unknown_type $key
	 * @param unknown_type $loopBlock
	 * @param unknown_type $else
	 */
	public function __construct($array, $key, $loopBlock, $else, $line) {
		$this->array = $array;
		$this->key = $key;
		$this->loopBlock = $loopBlock;
		$this->else = $else;
		$this->line = $line;
	}
	
	public function accept(IVisitor $visitor) {
		$visitor->visitForeachDirective($this);
	}
	
	public function getLineNumber() {
		return $this->line;
	}
}

class ASTBlock implements IASTNode {
	
	public $nodes;
	
	public function __construct() {
		$this->nodes = array();
	}
	
	public function addNode(IASTNode $node) {
		$this->nodes[] = $node;	
	}
	
	public function accept(IVisitor $visitor) {
		$visitor->visitBlock($this);
	}
}

class ASTSmurk implements IASTNode {
	
	public $smurk;
	
	function __construct($smurk) {
		$this->smurk = $smurk;
	}
	
	public function accept(IVisitor $visitor) {
		$visitor->visitSmurk($this);
	}
}

class ASTEqual implements IASTNode {
	
	public $left;
	public $right;
	
	public function __construct($left, $right) {
		$this->left = $left;
		$this->right = $right;
	}
	
	public function accept(IVisitor $visitor) {
		$visitor->visitEqual($this);
	}
}

class ASTNotEqual implements IASTNode {
	
	public $left;
	public $right;
	
	public function __construct($left, $right) {
		$this->left = $left;
		$this->right = $right;
	}
	
	public function accept(IVisitor $visitor) {
		$visitor->visitNotEqual($this);
	}
}


class ASTNot implements IASTNode {
	
	public $expr;
	
	public function __construct(IASTNode $expr) {
		$this->expr = $expr;
	}
	
	public function accept(IVisitor $visitor) {
		$visitor->visitNot($this);
	}
}

class ASTParenthesis implements IASTNode {

	public $expr;
	
	public function __construct(IASTNode $expr) {
		$this->expr = $expr;
	}
	
	public function accept(IVisitor $visitor) {
		$visitor->visitParenthesis($this);	
	}
}

class ASTAdd implements IASTNode {
	
	public $left;
	public $right;
	
	function __construct($left, $right) {
		$this->left = $left;
		$this->right = $right;
	}
	
	public function accept(IVisitor $visitor) {
		$visitor->visitAdd($this);
	}
}

class ASTLiteral implements IASTNode {
	
	public $value;
	
	function __construct($value) {
		$this->value = $value;
	}
	
	public function accept(IVisitor $visitor) {
		$visitor->visitLiteral($this);
	}
}

class ASTNumber implements IASTNode {

	public $value;
	
	function __construct($value) {
		$this->value = $value;	
	}
	
	public function accept(IVisitor $visitor) {
		$visitor->visitNumber($this);
	}
}

class ASTScalarObject implements IASTNode {

	public $scalar;
	public $modifiers;
	
	public function __construct($scalar, $modifiers) {
		$this->scalar = $scalar;
		$this->modifiers = $modifiers;
	}
	
	public function accept(IVisitor $visitor) {
		$visitor->visitScalarObject($this);
	}
}

class ASTSub implements IASTNode {
	
	public $left;
	public $right;
	
	function __construct($left, $right) {
		$this->left = $left;
		$this->right = $right;
	}
	
	public function accept(IVisitor $visitor) {
		$visitor->visitSub($this);
	}
}

class ASTMultiply implements IASTNode {
	
	public $left;
	public $right;
	
	function __construct($left, $right) {
		$this->left = $left;
		$this->right = $right;
	}
	
	public function accept(IVisitor $visitor) {
		$visitor->visitMultiply($this);
	}
}

class ASTDivide implements IASTNode {
	
	public $left;
	public $right;
	
	function __construct($left, $right) {
		$this->left = $left;
		$this->right = $right;
	}
	
	public function accept(IVisitor $visitor) {
		$visitor->visitDivide($this);
	}
}

class ASTModulus implements IASTNode {
	
	public $left;
	public $right;
	
	function __construct($left, $right) {
		$this->left = $left;
		$this->right = $right;
	}
	
	public function accept(IVisitor $visitor) {
		$visitor->visitModulus($this);
	}
}

class ASTLogicalOr implements IASTNode {

	public $left;
	public $right;
	
	function __construct($left, $right) {
		$this->left = $left;
		$this->right = $right;
	}
	
	public function accept(IVisitor $visitor) {
		$visitor->visitLogicalOr($this);
	}
}

class ASTLogicalAnd implements IASTNode {

	public $left;
	public $right;
	
	function __construct($left, $right) {
		$this->left = $left;
		$this->right = $right;
	}
	
	public function accept(IVisitor $visitor) {
		$visitor->visitLogicalAnd($this);
	}
}

class ASTGreaterThan implements IASTNode {
	
	public $left;
	public $right;
	
	function __construct($left, $right) {
		$this->left = $left;
		$this->right = $right;
	}
	
	public function accept(IVisitor $visitor) {
		$visitor->visitGreaterThan($this);
	}
}

class ASTGreaterOrEqual implements IASTNode {
	
	public $left;
	public $right;
	
	function __construct($left, $right) {
		$this->left = $left;
		$this->right = $right;
	}
	
	public function accept(IVisitor $visitor) {
		$visitor->visitGreaterOrEqual($this);
	}
}

class ASTLessThan implements IASTNode {
	public $left;
	public $right;
	
	function __construct($left, $right) {
		$this->left = $left;
		$this->right = $right;
	}
	
	public function accept(IVisitor $visitor) {
		$visitor->visitLessThan($this);
	}
}

class ASTLessOrEqual implements IASTNode {
	public $left;
	public $right;
	
	function __construct($left, $right) {
		$this->left = $left;
		$this->right = $right;
	}
	
	public function accept(IVisitor $visitor) {
		$visitor->visitLessOrEqual($this);
	}
}
?>